package base.loader
{
	import flash.events.EventDispatcher;
	
	public class LoaderQueue extends EventDispatcher
	{
		/**
		 *全部加载项
		 */		
		private var _allList:Vector.<BaseLoader>;
		
		/**
		 *当前队列全部加载项(用来处理加载) 
		 */		
		private var _loadingList:Vector.<BaseLoader>;
		/**
		 * 加载项未完成的总计
		 */		
		private var _loadingCount:int=0;
		/**
		 *进度值 
		 */		
		private var _progress:Number=0;
		/**
		 *传递的数据 
		 */		
		private var _transferData:*;
		private var _length:int;
		/**
		 *同时最大加载个数 
		 */		
		private var _maxLoadNum:int;
		
		/**
		 *加载队列 
		 * @param maxLoadNum 同时最大加载个数
		 * 
		 */		
		public function LoaderQueue(maxLoadNum:int=1)
		{
			_maxLoadNum=maxLoadNum;
			_allList=new Vector.<BaseLoader>();
			_loadingList=new Vector.<BaseLoader>();
		}
		
		/**
		 *增加加载项 
		 */		
		public function addLoader(baseLoader:BaseLoader):void
		{
			_allList.push(baseLoader);
			_loadingList.push(baseLoader);
			_loadingCount+=1;
		}
		
		/**
		 *执行队列中的加载 
		 * 
		 */			
		public function execute():void
		{
			if(!_loadingList || _loadingList.length<=0) return;
			var i:int=0;
			while(i<_maxLoadNum && _loadingList.length>0)
			{
				var baseLoader:BaseLoader= _loadingList.shift();
				baseLoader.addEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
				baseLoader.addEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
				baseLoader.execute();
				i++;
			}
		}
		
		private function __onLoadComplete(evt:LoaderEvent):void
		{
			_loadingCount-=1;
			var baseLoader:BaseLoader=evt.currentTarget as BaseLoader;
			baseLoader.removeEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
			baseLoader.removeEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
			if(evt.baseLoader)
			{
				evt.baseLoader.removeEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
				evt.baseLoader.removeEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
			}
			baseLoader=null;
			
			if(isAllComplete)
			{
				removeEvent();
				dispatchEvent(new LoaderEvent(LoaderEvent.COMPLETE_QUEUE, null, this));
			}
			else
			{
				execute();
			}
		}
		
		/**
		 *进度处理 
		 * @param evt
		 * 
		 */		
		private function __onLoadProgress(evt:LoaderEvent):void
		{
			var average:Number=100/_allList.length;//平均分配每个加载项所占总比值
			_progress=(_allList.length-_loadingCount)*average;//按加载项计算,取得完成项总计
			_progress+=evt.baseLoader.progress*(average/100);
			dispatchEvent(new LoaderEvent(LoaderEvent.QUEUE_PROGRESS, null, this));
		}
		
		private function removeEvent():void
		{
			for each(var baseLoader:BaseLoader in _loadingList)
			{
				baseLoader.removeEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
				baseLoader.removeEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
			}
			for each(baseLoader in _allList)
			{
				baseLoader.removeEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
				baseLoader.removeEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
			}
		}
		
		/**
		 *取得列表中的加载是否已全部加载完成(非全部成功) 
		 */		
		public function get isAllComplete():Boolean
		{
//			return _loadingList==null || _loadingList.length<=0;
			return _loadingCount<=0;
		}
		
		/**
		 *进度值 
		 * @return 
		 * 
		 */		
		public function get progress():int
		{
			return _progress;
		}
		
		public function dispose():void
		{			
			while(_loadingList && _loadingList.length>0)
			{
				var bl:BaseLoader=_loadingList.shift();
				bl.removeEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
				bl.removeEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
				bl.dispose();
				bl=null;
			}
			_loadingList=null;
			
			while(_allList && _allList.length>0)
			{
				bl=_allList.shift();
				bl.removeEventListener(LoaderEvent.COMPLETE, __onLoadComplete);
				bl.removeEventListener(LoaderEvent.PROGRESS, __onLoadProgress);
				bl.dispose();
				bl=null;
			}
			_allList=null;
			_transferData=null;
		}

		/**
		 *传递的数据 
		 */
		public function get transferData():*
		{
			return _transferData;
		}

		/**
		 * @private
		 */
		public function set transferData(value:*):void
		{
			_transferData = value;
		}
		
		/**
		 *加载项总长度 
		 */
		public function get length():int
		{
			return _allList.length;
		}
	}
}